package com.lnyt.serviceImpl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.lnyt.dao.t12306.TicketTaskMapper;
import com.lnyt.dao.t12306.TicketStore;
import com.lnyt.dao.t12306.TicketUserMapper;
import com.lnyt.dao.t12306.TrainStationMapper;
import com.lnyt.pojo.ticket.TicketTask;
import com.lnyt.pojo.ticket.TicketUser;
import com.lnyt.pojo.ticket.TrainStation;
import com.lnyt.service.TicketUserService;
import com.lnyt.util.CheckUtil;
import com.lnyt.util.factroy.OkHttpClientFactroy;
import com.lnyt.util.factroy.TicketFactroy;
import okhttp3.OkHttpClient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;


@Service
@Transactional
public class TicketUserServiceImp implements TicketUserService {
    // 车站静态变量
    private static Map<String, TrainStation> stationMap;
    // 缓存
    @Resource
    private TicketStore ticketStore;
    // 数据库Dao
    @Resource
    private TicketTaskMapper ticketTaskMapper;
    @Resource
    private TicketUserMapper ticketUserMapper;
    @Resource
    private TrainStationMapper trainStationMapper;
    // 读写锁
    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();


    @Override
    public String getStationInfoAll() {
        Map<String, List<TrainStation>> resultMap = new HashMap<>();

        JSONArray resJson = new JSONArray();
        JSONObject hotStations = new JSONObject();

        if (stationMap == null) {
            stationMap = new HashMap<>();
            List<TrainStation> stationList = trainStationMapper.selectAll();

            for (TrainStation station : stationList) {
                stationMap.put(station.getSymbol(), station);
            }
        }

        for (TrainStation station : stationMap.values()) {
            String fistChar = String.valueOf(station.getPinYin3().charAt(0)).toUpperCase();

            if (!resultMap.containsKey(fistChar)) {
                resultMap.put(fistChar, new ArrayList<>());
            }

            resultMap.get(fistChar).add(station);
        }

        for (Map.Entry<String, List<TrainStation>> entry : resultMap.entrySet()) {
            JSONObject stationGroup = new JSONObject();
            JSONArray stationList = new JSONArray();

            for (TrainStation station : entry.getValue()) {
                JSONObject stationJson = new JSONObject();

                stationJson.put("value", station.getSymbol());
                stationJson.put("label", station.getNameCN());
                stationList.add(stationJson);
            }

            stationGroup.put("value", entry.getKey());
            stationGroup.put("label", entry.getKey());
            stationGroup.put("children", stationList);
            resJson.add(stationGroup);
        }

//        resJson.add(0, hotStations);
        return JSON.toJSONString(resJson);
    }

    @Override
    public String userSignUp(JSONObject reqData) {
        String result = null;
        String userName = reqData.getString("username");
        String passWord = reqData.getString("password");

        String inputUserMd5 = CheckUtil.calcMd5(userName);
        String inputPassMd5 = CheckUtil.calcMd5(passWord);

        TicketUser ticketUser = TicketFactroy.creatTicketUser();
        ticketUser.setUserName(userName);

        if (ticketStore.getTicketUserMap().containsKey(inputUserMd5)) {
            ticketUser = ticketStore.getTicketUserMap().get(inputUserMd5);
        } else {
            ticketUser = ticketUserMapper.select(ticketUser);
            ticketUser.setTicketStatus(TicketStore.NOLOGIN);
        }

        if (ticketUser == null) {
            // 无此用户
            result = "{\"status\":2}";
            return result;
        }

        String passWordMd5 = ticketUser.getPassWord();

        if (passWordMd5 != null && passWordMd5.equals(inputPassMd5)) {
            JSONObject resJson = (JSONObject) JSONObject.toJSON(ticketUser);
            resJson.put("status", 0);
            resJson.remove("passWord");
            resJson.remove("ticketPassWord");
            result = resJson.toJSONString();

            // 判断是否为新增项
            if (!ticketStore.getTicketUserMap().containsKey(inputUserMd5)) {
                // 增加订单表容器
                ticketUser.setTicketTaskMap(new HashMap<>());
                // 增加请求对象
                ticketUser.setOkHttpClient(OkHttpClientFactroy.creator());

                ticketStore.getTicketUserMap().put(inputUserMd5, ticketUser);
            }
        } else {
            //  密码错误
            result = "{\"status\":1}";
        }

        return result;
    }

    @Override
    public String userUpdata(JSONObject reqData) {
        String result = "{\"status\":1}";

        TicketUser ticketUser = JSONObject.parseObject(reqData.toJSONString(), TicketUser.class);

        if (ticketUser != null) {
            ticketUserMapper.updata(ticketUser);
            result = "{\"status\":0}";
        }

        return result;
    }

    @Override
    public TicketUser getTikcetUser(String userMd5) {
        TicketUser ticketUser = ticketStore.getTicketUserMap().get(userMd5);

        if (ticketUser == null) {
            ticketUser = TicketFactroy.creatTicketUser();
            ticketStore.getTicketUserMap().put(userMd5, ticketUser);
        }

        return ticketUser;
    }


    @Override
    public void insertTask(TicketTask ticketTask, OkHttpClient okHttpClient) {
        readWriteLock.writeLock().lock();
        String fromStation = ticketTask.getFromStation();
        String toStation = ticketTask.getToStation();

        try {
            ticketTask.setFromStationName(stationMap.get(fromStation).getNameCN());
            ticketTask.setToStationName(stationMap.get(toStation).getNameCN());

            ticketTaskMapper.insert(ticketTask);

            Integer taskId = ticketTaskMapper.selectNewID();
            String userId = ticketTask.getUserId();
            ticketTask.setId(taskId);

            ticketStore.insetUserTask(userId, ticketTask);
            ticketStore.setUserOkHttpClient(userId, okHttpClient);

        } catch (Exception exc) {
            exc.printStackTrace();
        } finally {
            readWriteLock.writeLock().unlock();
        }
    }

    @Override
    public void deleteTask(TicketTask ticketTask, OkHttpClient okHttpClient) {
        readWriteLock.writeLock().lock();

        try {
            ticketTaskMapper.delete(ticketTask);

            String userId = ticketTask.getUserId();
            ticketStore.deleteUserTask(userId, ticketTask);

        } catch (Exception exc) {
            exc.printStackTrace();
        } finally {
            readWriteLock.writeLock().unlock();
        }
    }

    @Override
    public void updataTask(TicketTask ticketTask, OkHttpClient okHttpClient) {
        readWriteLock.writeLock().lock();

        try {
            ticketTaskMapper.update(ticketTask);

            String userId = ticketTask.getUserId();
            ticketStore.updataUserTask(userId, ticketTask);

        } catch (Exception exc) {
            exc.printStackTrace();
        } finally {
            readWriteLock.writeLock().unlock();
        }
    }

    @Override
    public String selectTask(TicketTask ticketTask, OkHttpClient okHttpClient) {
        readWriteLock.writeLock().lock();
        String result = null;

        try {
            List<TicketTask> ticketTasks = ticketTaskMapper.select(ticketTask);
            List<TicketTask> ResTicketTasks = new ArrayList<>();

            for (TicketTask item : ticketTasks) {
                String userId = item.getUserId();
                String status = item.getStatus();

                if (status != null && !status.equals("Cencel")) {
                    ResTicketTasks.add(item);
                    ticketStore.insetUserTask(userId, item);
                }
            }

            result = JSONArray.toJSONString(ResTicketTasks);

        } catch (Exception exc) {
            exc.printStackTrace();
        } finally {
            readWriteLock.writeLock().unlock();
        }

        return result;
    }



}
